#include "gtest/gtest.h"
#include "../src/intSLList.hpp"
using namespace std;

class TestIntSLList : public testing::Test
{
    protected:
        virtual void SetUp(){

        }

        virtual void TearDown(){

        }
};

TEST_F(TestIntSLList, TestEmpty){
    IntSLList a;
    EXPECT_TRUE(a.isEmpty());
}

TEST_F(TestIntSLList, TestAddtoHead){
    IntSLList a;
    a.addToHead(1);
    a.addToHead(2);
    a.addToHead(3);
    a.addToHead(4);
    a.addToHead(5);
    a.addToHead(6);
    EXPECT_FALSE(a.isEmpty());
    int* info = a.delFromHead();
    EXPECT_EQ(*info, 6);
    info = a.delFromHead();
    EXPECT_EQ(*info, 5);
    info = a.delFromHead();
    EXPECT_EQ(*info, 4);
    info = a.delFromHead();
    EXPECT_EQ(*info, 3);
    info = a.delFromHead();
    EXPECT_EQ(*info, 2);
    info = a.delFromHead();
    EXPECT_EQ(*info, 1);
    EXPECT_TRUE(a.isEmpty());
}

TEST_F(TestIntSLList, TestAddtoTail){
    IntSLList a;
    a.addToTail(1);
    a.addToTail(2);
    a.addToTail(3);
    a.addToTail(4);
    a.addToTail(5);
    a.addToTail(6);
    EXPECT_FALSE(a.isEmpty());
    int* info = a.delFromHead();
    EXPECT_EQ(*info, 1);
    info = a.delFromHead();
    EXPECT_EQ(*info, 2);
    info = a.delFromHead();
    EXPECT_EQ(*info, 3);
    info = a.delFromHead();
    EXPECT_EQ(*info, 4);
    info = a.delFromHead();
    EXPECT_EQ(*info, 5);
    info = a.delFromHead();
    EXPECT_EQ(*info, 6);
    EXPECT_TRUE(a.isEmpty());
}

TEST_F(TestIntSLList, TestAddDelRandom){
    IntSLList a;
    a.addToTail(1);
    a.addToTail(2);
    a.addToHead(3);
    a.addToTail(4);
    a.addToHead(5);
    a.addToHead(6);
    a.addToTail(7);
    a.addToTail(8);

    EXPECT_FALSE(a.isEmpty());
    int* info = a.delFromHead();
    EXPECT_EQ(*info, 6);

    info = a.delFromTail();
    EXPECT_EQ(*info, 8);

    info = a.delFromHead();
    EXPECT_EQ(*info, 5);

    info = a.delFromTail();
    EXPECT_EQ(*info, 7);

    info = a.delFromTail();
    EXPECT_EQ(*info, 4);

    info = a.delFromHead();
    EXPECT_EQ(*info, 3);

    info = a.delFromHead();
    EXPECT_EQ(*info, 1);

    info = a.delFromTail();
    EXPECT_EQ(*info, 2);

    EXPECT_TRUE(a.isEmpty());
}


TEST_F(TestIntSLList, TestEmptyListdelFromHead){
    IntSLList a;
    int* info = a.delFromHead();
    EXPECT_EQ(info, nullptr);
}

TEST_F(TestIntSLList, TestEmptyListdelFromTail){
    IntSLList a;
    int* info = a.delFromTail();
    EXPECT_EQ(info, nullptr);
}

TEST_F(TestIntSLList, TestOneListdelFromHead){
    IntSLList a;
    a.addToHead(1);
    int* info = a.delFromHead();
    EXPECT_NE(info, nullptr);
    EXPECT_EQ(*info, 1);
    EXPECT_TRUE(a.isEmpty());
}

TEST_F(TestIntSLList, TestOneListdelFromTail){
    IntSLList a;
    a.addToHead(1);
    int* info = a.delFromTail();
    EXPECT_NE(info, nullptr);
    EXPECT_EQ(*info, 1);
    EXPECT_TRUE(a.isEmpty());
}

TEST_F(TestIntSLList, TestEmptyDelNode){
    IntSLList a;
    a.delNode(5);
}

TEST_F(TestIntSLList, TestOneDelNode){
    IntSLList a;
    a.addToHead(5);
    EXPECT_TRUE(a.isInList(5));
    a.delNode(5);
    EXPECT_FALSE(a.isInList(5));
}

TEST_F(TestIntSLList, TestDelNode){
    IntSLList a;
    a.addToHead(5);
    a.addToHead(3);
    a.addToTail(1);
    EXPECT_TRUE(a.isInList(5));
    a.delNode(5);
    EXPECT_FALSE(a.isInList(5));
}